/*
**  game.c
**  Copyright 2011, Zane Sims
**
**  This file is part of brick-breaker-game.
**
**  brick-breaker-game is free software: you can redistribute it
**  and/or modify it under the terms of the GNU General Public
**  License as published by the Free Software Foundation, either
**  version 3 of the License, or (at your option) any later version.
**
**  brick-breaker-game is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with brick-breaker-game.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <allegro5/allegro.h>
#include <allegro5/allegro_native_dialog.h>
#include <stdlib.h>
#include <time.h>

#include "common.h"
#include "gui.h"

#define SCREEN_W					800
#define SCREEN_H					600
#define FPS							60

#define ITEM_TYPE_NONE				-1
#define ITEM_TYPE_KILL				0
#define ITEM_TYPE_SHRINK_PADDLE		1
#define ITEM_TYPE_GROW_PADDLE		2
#define ITEM_TYPE_SUPER_BALL		3

typedef struct _Item
{
	int x;
	int y;
	int type;
}Item;

Item items[2];
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_EVENT_QUEUE *event_queue = NULL;
ALLEGRO_TIMER *frame_timer = NULL;
ALLEGRO_TIMER *ball_timer = NULL;
float ball_x;
float ball_y;
float ball_x_inc; /* used to increment the ball position during motion */ 
float ball_y_inc; /* used to increment the ball position during motion */
float paddle_x;
float paddle_y;
int paddle_size;
int lives = 0;
int died = 0;
int super_ball = 0;
int item_alternate = 0;
int32_t points = 0;
int32_t points_check = 0;
int32_t high_scores[10];
char high_score_initials[10][4];
char score_string[50] = "";
char initials[4] = {'-', '-', '-', '\0'};
int level = 1;
int paused = 0;
ClickableSet *start_screen_set = NULL;
Clickable* start_button = NULL;
Clickable* exit_button = NULL;
ALLEGRO_FONT *button_font = NULL;
ALLEGRO_FONT *message_font = NULL;
ALLEGRO_FONT *score_font = NULL;
ALLEGRO_FONT *initials_font = NULL;

void hold_mouse();
void release_mouse();
void initials_loop();
void generate_item(Item *item, int x, int y);
void show_message(const char* msg, ALLEGRO_COLOR c);
int button_click(int mx, int my, struct _Clickable *c);
void game_loop();
void write_high_scores();
void read_high_scores();
void load_next_level();
void reset_ball_and_paddle();
void draw_ball();
void draw_paddle();
void draw_walls();
void move_ball();
void move_paddle(int dx);
void set_paddle_size(int size);
void do_collisions();
int intersects(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2);
void clean_up();

int main(int argc, char **argv)
{
	int i = 0;

	APP_MODE = GAME;
	BRICK_GRID_X1 = 20;
	BRICK_GRID_Y1 = 50;
	BRICK_GRID_X2 = BRICK_GRID_X1 + (BRICK_GRID_W*BRICK_W);
	BRICK_GRID_Y2 = BRICK_GRID_Y1 + (BRICK_GRID_H*BRICK_H);

	srand(time(NULL));

	if(!al_init())
		error_exit("failed to initialize allegro!");
 
	if(!al_init_image_addon())
		error_exit("failed to initialize image addon");

	al_init_font_addon();

	if(!al_init_ttf_addon())
		error_exit("failed to initialize ttf addon");

	if(!al_init_primitives_addon())
		error_exit("failed to initialize primitives addon");

	if(!al_install_mouse())
		error_exit("failed to initialize the mouse!");

	if(!al_install_keyboard())
		error_exit("failed to initialize the keyboard!");
 
	if(!(frame_timer = al_create_timer(1.0 / FPS)))
		error_exit("failed to create frame_timer!");

	if(!(ball_timer = al_create_timer(0.025)))
		error_exit("failed to create frame_timer!");

	if(!(display = al_create_display(SCREEN_W, SCREEN_H)))
		error_exit("failed to create display!");

	if(!(event_queue = al_create_event_queue()))
		error_exit("failed to create event_queue!");
 
	al_register_event_source(event_queue, al_get_display_event_source(display));
	al_register_event_source(event_queue, al_get_timer_event_source(frame_timer));
	al_register_event_source(event_queue, al_get_timer_event_source(ball_timer));
	al_register_event_source(event_queue, al_get_mouse_event_source());
	al_register_event_source(event_queue, al_get_keyboard_event_source());

	al_set_target_bitmap(al_get_backbuffer(display));
	al_clear_to_color(al_map_rgb(0,0,0));
	al_flip_display();

	load_images();

	button_font = al_load_font("fonts/FreeMonoBold.ttf", 14, 0);
	message_font = al_load_font("fonts/FreeSansBold.ttf", 24, 0);
	score_font = al_load_font("fonts/FreeMonoBold.ttf", 20, 0);
	initials_font = al_load_font("fonts/FreeMonoBold.ttf", 46, 0);

	start_screen_set = new_clickable_set();

	start_button = malloc(sizeof(Clickable));
	start_button->parent_set = start_screen_set;
	start_button->icon = NULL;
	start_button->img = NULL;
	start_button->back_color = al_map_rgb(50,50,50);
	start_button->transparent = 0;
	start_button->font = button_font;
	start_button->text_color = al_map_rgb(255,255,255);
	strcpy(start_button->text, "Start Game");
	start_button->text_align = ALLEGRO_ALIGN_CENTRE;
	start_button->border_size = 2;
	start_button->border_color = al_map_rgb(200,200,200);
	start_button->x1 = 40;
	start_button->y1 = 400;
	start_button->x2 = start_button->x1 + 140;
	start_button->y2 = start_button->y1 + 25;
	start_button->hovering = 0;
	start_button->click = &button_click;
	start_button->hover = NULL;
	reg_clickable(start_button);

	exit_button = malloc(sizeof(Clickable));
	exit_button->parent_set = start_screen_set;
	exit_button->icon = NULL;
	exit_button->img = NULL;
	exit_button->back_color = al_map_rgb(50,50,50);
	exit_button->transparent = 0;
	exit_button->font = button_font;
	exit_button->text_color = al_map_rgb(255,255,255);
	strcpy(exit_button->text, "Quit Playing");
	exit_button->text_align = ALLEGRO_ALIGN_CENTRE;
	exit_button->border_size = 2;
	exit_button->border_color = al_map_rgb(200,200,200);
	exit_button->x1 = start_button->x1;
	exit_button->y1 = start_button->y2 + 10;
	exit_button->x2 = start_button->x2;
	exit_button->y2 = exit_button->y1 + start_button->y2 - start_button->y1;
	exit_button->hovering = 0;
	exit_button->click = &button_click;
	exit_button->hover = NULL;
	reg_clickable(exit_button);

	read_high_scores();

	al_start_timer(frame_timer);

	while(1)
	{
		ALLEGRO_EVENT ev;
		al_wait_for_event(event_queue, &ev);
 
		if(ev.type == ALLEGRO_EVENT_TIMER)
		{
			if(ev.any.source == al_get_timer_event_source(frame_timer))
			{
				//redraw screen
				al_clear_to_color(al_map_rgb(0,0,0));

				al_draw_bitmap(start_screen_img, 0, 0, 0);

				draw_clickable(start_button);
				draw_clickable(exit_button);

				al_draw_text(button_font, al_map_rgb(255,255,255), 40, 520, ALLEGRO_ALIGN_LEFT, "Copyright © 2011, Zane Sims");

				for(i=0;i<10;i++)
				{
					al_draw_text(score_font, al_map_rgb(255,255,255), 550, 250+(i*al_get_font_line_height(score_font))+(i*10)+10, ALLEGRO_ALIGN_LEFT, high_score_initials[i]);
					al_draw_textf(score_font, al_map_rgb(255,255,255), 600, 250+(i*al_get_font_line_height(score_font))+(i*10)+10, ALLEGRO_ALIGN_LEFT, "%09d", high_scores[i]);
				}

				al_flip_display();
			}
		}
		else if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
		{
			if(ev.keyboard.keycode==ALLEGRO_KEY_ESCAPE)
				return 1;
		}
		else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
		{}
		else if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN)
		{
			process_clickable_set_clicks(start_screen_set, ev.mouse.x, ev.mouse.y);
		}
	}
 
	clean_up();
	return 0;
}


int button_click(int mx, int my, struct _Clickable *c)
{
	if(c == start_button)
		game_loop();
	else if(c == exit_button)
	{
		clean_up();
		exit(0);
	}

	return 0;
}

void hold_mouse()
{
	al_grab_mouse(display);
	al_hide_mouse_cursor(display);
	al_set_mouse_xy(display, paddle_x+al_get_bitmap_width(paddle_img[paddle_size]), SCREEN_H/2);
}

void release_mouse()
{
	al_ungrab_mouse();
	al_show_mouse_cursor(display);
	al_set_mouse_xy(display, SCREEN_W/2, SCREEN_H/2);
}

void game_loop()
{
	if(!load_level("levels/001.lvl"))
		error_exit("Error: cannot load '001.lvl'!");

	/* init the player data */
	level = 1;
	lives = 3;
	points = 0;
	points_check = 0;
	paddle_size = MEDIUM_PADDLE;
	reset_ball_and_paddle();

	hold_mouse();

	al_start_timer(ball_timer);

	while(1)
	{
		ALLEGRO_EVENT ev;
		al_wait_for_event(event_queue, &ev);
 
		if(paused && ev.type==ALLEGRO_EVENT_KEY_DOWN && ev.keyboard.keycode == ALLEGRO_KEY_SPACE)
		{
			paused = 0;
			hold_mouse();
			al_start_timer(ball_timer);
			al_start_timer(frame_timer);
		}
		else if(paused)
			al_flush_event_queue(event_queue); /* flush the queue in case I missed something and it built up while paused*/
		else if(ev.type == ALLEGRO_EVENT_TIMER)
		{
			if(ev.any.source == al_get_timer_event_source(ball_timer))
			{
				move_ball();
				
				if(items[0].type != ITEM_TYPE_NONE)
					items[0].y += 6;

				if(items[1].type != ITEM_TYPE_NONE)
					items[1].y += 6;

				do_collisions();

				if(bricks_remaining == 0)
				{
					show_message("Level clear!", al_map_rgb(100, 100, 255));
					reset_ball_and_paddle();					
					load_next_level();					
				}
				else if(died)
				{
					lives--;
					
					if(lives < 0)
					{
						show_message("Game Over!", al_map_rgb(255, 100, 100));
						write_high_scores();
						break;
					}
					else
					{
						show_message("You Missed!", al_map_rgb(255, 255, 0));
						reset_ball_and_paddle();
					}
				}				
			}
			else if(ev.any.source == al_get_timer_event_source(frame_timer))
			{
				//redraw screen
				al_clear_to_color(al_map_rgb(0,0,0));
				draw_ball();			
				draw_walls();
				draw_paddle();
				draw_bricks(0);

				if(item_alternate < 30)
				{
					if(items[0].type != ITEM_TYPE_NONE)
						al_draw_bitmap(item_imgs[items[0].type], items[0].x, items[0].y, 0);

					if(items[1].type != ITEM_TYPE_NONE)
						al_draw_bitmap(item_imgs[items[1].type], items[1].x, items[1].y, 0);
				}
				else
				{
					if(items[1].type != ITEM_TYPE_NONE)
						al_draw_bitmap(item_imgs[items[1].type], items[1].x, items[1].y, 0);
					if(items[0].type != ITEM_TYPE_NONE)
						al_draw_bitmap(item_imgs[items[0].type], items[0].x, items[0].y, 0);
				}

				item_alternate++;

				if(item_alternate > 60)
					item_alternate = 0;

				al_draw_textf(score_font, al_map_rgb(255,255,255), 32, 16, ALLEGRO_ALIGN_LEFT, "SCORE: %09d", points);

				al_draw_bitmap(ball_img, 724, 22, 0);
				al_draw_textf(button_font, al_map_rgb(255,255,255), 740, 18, ALLEGRO_ALIGN_LEFT, "X %02d", lives);

				al_flip_display();
			}
		}
		else if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
		{
			if(ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
			{
				int result = 0;

				al_stop_timer(ball_timer);
				al_stop_timer(frame_timer);

				release_mouse();

				result = al_show_native_message_box(display, "Warning!", "Warning!", "You are about to quit this game. Are you sure you want to continue?", NULL, ALLEGRO_MESSAGEBOX_YES_NO);

				al_start_timer(frame_timer);

				if(result == 1)
					break;

				hold_mouse();
				al_flush_event_queue(event_queue); /* flush the queue in case I missed something and it built up while paused*/
				al_start_timer(ball_timer);
			}
			else if(ev.keyboard.keycode == ALLEGRO_KEY_SPACE)
			{
				int msg_h = al_get_font_line_height(message_font);

				al_stop_timer(ball_timer);
				al_stop_timer(frame_timer);

				al_clear_to_color(al_map_rgb(0,0,0));
				al_draw_text(message_font, al_map_rgb(255,255,255), SCREEN_W/2.0, (SCREEN_H/2.0)-(msg_h/2.0), ALLEGRO_ALIGN_CENTRE, "PAUSED");
				al_flip_display();

				paused = 1;
				release_mouse();
			}
		}
		else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
		{}
		else if(ev.type == ALLEGRO_EVENT_MOUSE_AXES)
			move_paddle(ev.mouse.dx);
	}

	al_stop_timer(ball_timer);

	al_flush_event_queue(event_queue);

	release_mouse();
}

void reset_ball_and_paddle()
{
	items[0].type = ITEM_TYPE_NONE;
	items[1].type = ITEM_TYPE_NONE;
	super_ball = 0;
	ball_x = (SCREEN_W / 2.0) - 4;
	ball_y = 550;
	ball_x_inc = 1;
	ball_y_inc = -5;
	paddle_x = SCREEN_W / 2.0 - al_get_bitmap_width(paddle_img[paddle_size]) / 2.0;
	paddle_y = SCREEN_H - al_get_bitmap_height(paddle_img[paddle_size]) - 8;
	al_set_mouse_xy(display, SCREEN_W/2, SCREEN_H/2);

	if(died)
	{
		died = 0;
		paddle_size = MEDIUM_PADDLE;
	}	
}

void write_high_scores()
{
	ALLEGRO_FILE *fp = NULL;
	int i = 0;
	int swap_at = -1;

	/* check to see if a swap needs to occur */
	for(i=0;i<10;i++)
	{
		if(high_scores[i] < points)
		{
			swap_at = i;
			break;
		}
	}

	/* if there is a new high score */
	if(swap_at != -1)
	{
		initials_loop();

		for(i=9;i>=0;i--)
		{
			if(i > swap_at)
			{
				strncpy(high_score_initials[i], high_score_initials[i-1], 3);
				high_scores[i] = high_scores[i-1];
			}
			else if(i == swap_at)
			{
				strncpy(high_score_initials[i], initials, 3);
				high_scores[i] = points;
				break;
			}
		}

		if((fp=al_fopen("scrs.data", "wb+")) != NULL)
		{
			for(i=0;i<10;i++)
			{
				al_fwrite32be(fp, high_scores[i]);
				al_fputs(fp, high_score_initials[i]);
			}
			al_fclose(fp);
		}
	}
}

void read_high_scores()
{
	ALLEGRO_FILE *fp = NULL;
	int i = 0;

	if((fp=al_fopen("scrs.data", "rb")) == NULL)
	{
		for(i=0;i<10;i++)
		{
			high_scores[i] = 0;
			strncpy(high_score_initials[i], "---", 3);
		}
	}
	else
	{
		for(i=0;i<10;i++)
		{
			high_scores[i] = al_fread32be(fp);
			high_score_initials[i][0] = al_fgetc(fp);
			high_score_initials[i][1] = al_fgetc(fp);
			high_score_initials[i][2] = al_fgetc(fp);
			high_score_initials[i][3] = '\0';
		}
	}

	if(fp != NULL)
		al_fclose(fp);
}

void initials_loop()
{
	al_stop_timer(ball_timer);

	int type_pos = 0;
	int key = 0;
	int uni = 0;

	while(1)
	{
		ALLEGRO_EVENT ev;
		al_wait_for_event(event_queue, &ev);
 
		if(ev.type == ALLEGRO_EVENT_TIMER && ev.any.source==al_get_timer_event_source(frame_timer))
		{
				//redraw screen
				al_clear_to_color(al_map_rgb(0,0,0));

				al_draw_text(message_font, al_map_rgb(100,255,100), SCREEN_W/2.0, 75, ALLEGRO_ALIGN_CENTRE, "CONGRATULATIONS!");
				al_draw_textf(message_font, al_map_rgb(100,255,100), SCREEN_W/2.0, 110, ALLEGRO_ALIGN_CENTRE, "YOU'VE GOT A HIGH SCORE: %09d!", points);
				al_draw_text(message_font, al_map_rgb(255,255,100), SCREEN_W/2.0, 200, ALLEGRO_ALIGN_CENTRE, "Enter your initials:");
				al_draw_text(initials_font, al_map_rgb(255,255,255), SCREEN_W/2.0, 320, ALLEGRO_ALIGN_CENTRE, initials);

				if(type_pos == 0)
					al_draw_text(initials_font, al_map_rgb(255,255,255), 358, 355, ALLEGRO_ALIGN_LEFT, "^  ");
				else if(type_pos == 1)
					al_draw_text(initials_font, al_map_rgb(255,255,255), 358, 355, ALLEGRO_ALIGN_LEFT, " ^ ");
				else if(type_pos >= 2)
					al_draw_text(initials_font, al_map_rgb(255,255,255), 358, 355, ALLEGRO_ALIGN_LEFT, "  ^");

				al_flip_display();
		}
		else if(ev.type == ALLEGRO_EVENT_KEY_CHAR)
		{
			uni = ev.keyboard.unichar;

			if(type_pos<3 && uni>=32 && uni<=128)
			{
				initials[type_pos] = uni;
				type_pos++;
			}
		}
		else if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
		{
			key = ev.keyboard.keycode;

			if(key==ALLEGRO_KEY_BACKSPACE && type_pos>0)
			{
				type_pos--;
				initials[type_pos] = '-';
			}
			else if(ev.keyboard.keycode == ALLEGRO_KEY_ENTER)
				break;
		}		
		else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
		{}
	}

	al_start_timer(ball_timer);
	al_flush_event_queue(event_queue);
}

void load_next_level()
{
	char filename[256] = "";

	level++;

	sprintf(filename,  "levels/%03d.lvl", level);

	if(!load_level(filename))
	{
		level = 1;

		if(!load_level("levels/001.lvl"))
			error_exit("Error: unable to load levels/001.lvl");
	}

	al_flush_event_queue(event_queue);
}

void draw_ball()
{
	al_draw_bitmap(ball_img, ball_x, ball_y, 0);
}

void draw_paddle()
{
	al_draw_bitmap(paddle_img[paddle_size], paddle_x, paddle_y, 0);
}

void draw_walls()
{
	al_draw_bitmap(top_wall_img, 0, 0, 0);
	al_draw_bitmap(left_wall_img, 0, 50, 0);
	al_draw_bitmap(right_wall_img, SCREEN_W-20, 50, 0);
}

void move_ball()
{
	ball_x += ball_x_inc;
	ball_y += ball_y_inc;
}

void move_paddle(int dx)
{
	int paddle_width = al_get_bitmap_width(paddle_img[paddle_size]);

	paddle_x += dx;

	if(paddle_x > SCREEN_W - paddle_width - 20)
		paddle_x = SCREEN_W - paddle_width - 20;
	else if(paddle_x < 20)
		paddle_x = 20;
}

void set_paddle_size(int size)
{
	int old_w = al_get_bitmap_width(paddle_img[paddle_size]);
	int new_w = al_get_bitmap_width(paddle_img[size]);

	paddle_size = size;

	paddle_x = paddle_x+(old_w/2) - (new_w/2);

	if(paddle_x < 20)
		paddle_x = 20;
	else if((paddle_x+new_w) > SCREEN_W-20)
		paddle_x = SCREEN_W - new_w - 20;

	al_set_mouse_xy(display, paddle_x+(new_w/2), paddle_y);
}

void do_collisions()
{
	int ball_dia = al_get_bitmap_width(ball_img);
	int paddle_w = al_get_bitmap_width(paddle_img[paddle_size]);
	int col_index_i = (ball_x-20) / BRICK_W;
	int	col_index_j = (ball_y-50) / BRICK_H;
	int i = 0;
	int j = 0;

	/* do it this way to prevent the wall from "jetstreaming" the ball */
	if(ball_x >= SCREEN_W-ball_dia-20)
	{
		ball_x_inc *= -1;
		ball_x = SCREEN_W-ball_dia-21;
	}
	else if(ball_x <= 20)
	{
		ball_x = 21;
		ball_x_inc *= -1;
	}

	/* if the ball hits the ceiling or falls too far down*/
	if(ball_y <= 50)
	{
		ball_y_inc *= -1;
		ball_y = 51;
	}
	else if(ball_y >= 600)
	{
		died = 1;
	}

	/* if the ball hits the paddle */
	if(ball_y+ball_dia >= paddle_y && ball_y+ball_dia <= paddle_y+8)
	{
		if(ball_x + (ball_dia*0.75) >= paddle_x && ball_x-(ball_dia*0.25) <= paddle_x+paddle_w)
		{
			int ball_pos = ball_x+(ball_dia/2) - paddle_x; /* get the ball's position relative to the paddle */
			float hit_perc = ((float)ball_pos / (paddle_w - ball_dia)) - 0.5;

/*			WAS TRYING THIS
			ball_x_inc = ball_x_inc + (hit_perc * 5);
			ball_y_inc *= -1;
*/
			ball_x_inc = (hit_perc * 10);
			ball_y_inc *= -1;


			/* WAS TRYING THIS OUT */
			/*if(!(hit_perc>=-.075 && hit_perc<=.075))
				ball_x_inc = hit_perc*5;
			ball_y_inc *= -1;*/
		}
	}


	/*	Brick collision - WARNING: This is very delicate code */
	if(col_index_j < BRICK_GRID_H)
	{
		int left = 0;
		int right = 0;
		int top = 0;
		int bottom = 0;
		int deflect = 0;
		int struck = 0;

		for(i=col_index_i;i<=col_index_i+1;i++)
		{
			for(j=col_index_j;j<=col_index_j+1;j++)
			{
				if(i<BRICK_GRID_W && j<BRICK_GRID_H)
				{
					if(bricks[i][j].type!=BRICK_TYPE_NONE && intersects(ball_x, ball_y, ball_dia, ball_dia, bricks[i][j].x, bricks[i][j].y, 38, 17))
					{
						struck = 0;

						if(intersects(ball_x, ball_y, ball_dia, ball_dia, bricks[i][j].x+4, bricks[i][j].y, 30, 4))
							top = 1;
						if(intersects(ball_x, ball_y, ball_dia, ball_dia, bricks[i][j].x+4, bricks[i][j].y+13, 30, 4))
							bottom = 1;
						if(intersects(ball_x, ball_y, ball_dia, ball_dia, bricks[i][j].x, bricks[i][j].y+4, 4, 9))
							left = 1;
						if(intersects(ball_x, ball_y, ball_dia, ball_dia, bricks[i][j].x+34, bricks[i][j].y+4, 4, 9))
							right = 1;

						if(right||left||top||bottom)
							struck = 1;

						/* if not super ball, then we need to bounce the ball off the brick */
						if(struck && ((!super_ball) || (super_ball && bricks[i][j].type==BRICK_TYPE_UNBREAKABLE)))
							deflect = 1;

						if(struck && bricks[i][j].type!=BRICK_TYPE_UNBREAKABLE && bricks[i][j].type!=BRICK_TYPE_EXPLODING)
						{

							if(bricks[i][j].type == BRICK_TYPE_INVISIBLE)
							{
								bricks[i][j].type = BRICK_TYPE_NORMAL;
								bricks[i][j].img_index = 20;
							}
							else
							{
								bricks[i][j].type = BRICK_TYPE_NONE;
								bricks_remaining--;
							}

							points += 10;

							if(items[0].type == ITEM_TYPE_NONE)
								generate_item(&(items[0]), bricks[i][j].x+(BRICK_W/2), bricks[i][j].y);
							else if(items[1].type == ITEM_TYPE_NONE)
								generate_item(&(items[1]), bricks[i][j].x+(BRICK_W/2), bricks[i][j].y);
						}
						else if(bricks[i][j].type == BRICK_TYPE_EXPLODING)
							explode_bricks(i, j);
					}					
				}
			}
		}

		if(deflect)
		{
		/*	if(left && right)
				ball_y_inc *= -1;
			else if(top && bottom)
				ball_x_inc *= -1;
		*/
				if( (left && ball_x_inc>0) || (right && ball_x_inc<0) )
					ball_x_inc *= -1;
				if( (top && ball_y_inc>0) || (bottom && ball_y_inc<0) )
					ball_y_inc *= -1;

		}
	}


	/* Item Collision */
	for(i=0;i<2;i++)
	{
		if(items[i].type != ITEM_TYPE_NONE)
		{
			if(items[i].y >= 600)
				items[i].type = ITEM_TYPE_NONE;
			else if(intersects(items[i].x, items[i].y, 38, 38, paddle_x, paddle_y, paddle_w, 8))
			{
				if(items[i].type==ITEM_TYPE_SHRINK_PADDLE && paddle_size>SMALL_PADDLE)
				{
					set_paddle_size(paddle_size-1);
					points += 15;
				}
				else if(items[i].type==ITEM_TYPE_GROW_PADDLE && paddle_size<XLARGE_PADDLE)
				{
					set_paddle_size(paddle_size+1);
					points += 25;
				}
				else if(items[i].type == ITEM_TYPE_KILL)
					died = 1;
				else if(items[i].type == ITEM_TYPE_SUPER_BALL)
				{
					super_ball = 1;
					points += 35;
				}

				items[i].type = ITEM_TYPE_NONE;
			}
		}
	}

	if(points-points_check >= 20000)
	{
		lives++;
		points_check = points;
	}
}

void show_message(const char* msg, ALLEGRO_COLOR c)
{
	int msg_h = al_get_font_line_height(message_font);

	al_stop_timer(ball_timer);
	al_stop_timer(frame_timer);

	al_clear_to_color(al_map_rgb(0,0,0));	
	al_draw_text(message_font, c, SCREEN_W/2.0, (SCREEN_H/2.0)-(msg_h/2.0), ALLEGRO_ALIGN_CENTRE, msg);
	al_flip_display();
	al_rest(2);

	al_flush_event_queue(event_queue);

	al_start_timer(ball_timer);
	al_start_timer(frame_timer);
}

void generate_item(Item *item, int x, int y)
{
	int r = rand() % 100;

	item->x = x-19;
	item->y = y;

	if(r<=92)
		item->type = ITEM_TYPE_NONE;
	else if(r>92 && r<=94)
		item->type = ITEM_TYPE_KILL;
	else if(r>94 && r<=96)
		item->type = ITEM_TYPE_SHRINK_PADDLE;
	else if(r>96 && r<=98)
		item->type = ITEM_TYPE_GROW_PADDLE;
	else if(r>98 && r<=100)
		item->type = ITEM_TYPE_SUPER_BALL;
}

int explode_bricks(int a, int b)
{
	int i = 0;
	int j = 0;
	int start_i;
	int start_j;
	int end_i;
	int end_j;
	int type;

	if(a==0)	start_i = 0;
	else		start_i = a-1;

	if(a==BRICK_GRID_W-1)	end_i = a;
	else					end_i = a+1;

	if(b==0)	start_j = 0;
	else		start_j = b-1;

	if(b==BRICK_GRID_H-1)	end_j = b;
	else					end_j = b+1;

	for(j=start_j;j<=end_j;j++)
	{
		for(i=start_i;i<=end_i;i++)
		{
			if(bricks[i][j].type != BRICK_TYPE_NONE)
			{
				type = bricks[i][j].type;

				if(type != BRICK_TYPE_UNBREAKABLE)
					bricks_remaining--;
				
				if(items[0].type == ITEM_TYPE_NONE)
					generate_item(&(items[0]), bricks[i][j].x+(BRICK_W/2), bricks[i][j].y);
				else if(items[1].type == ITEM_TYPE_NONE)
					generate_item(&(items[1]), bricks[i][j].x+(BRICK_W/2), bricks[i][j].y);

				bricks[i][j].type = BRICK_TYPE_NONE;
				bricks[i][j].explode_tick = 60;

				if(type == BRICK_TYPE_EXPLODING && !(a==i && b==j))
					explode_bricks(i, j);

				points += 10;
			}
		}
	}
}

int intersects(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2)
{
	if((x2>=x1 && x2<=x1+w1) || (x1>=x2 && x1<=x2+w2))
	{
		if((y2>=y1 && y2<=y1+h1) || (y1>=y2 && y1<=y2+h2))
			return 1;
	}

	return 0;
}

void clean_up()
{
	/*destroy things if they aren't NULL*/
	free_images();
	al_destroy_timer(frame_timer);
	al_destroy_timer(ball_timer);
	al_destroy_display(display);
	al_destroy_event_queue(event_queue);
	al_destroy_font(button_font);
	al_destroy_font(message_font);
	al_destroy_font(score_font);
	al_destroy_font(initials_font);
}



